package fr.curriculumvitae.anthony.stephan.backend;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;

import com.parse.FindCallback;
import com.parse.GetCallback;
import com.parse.GetDataCallback;
import com.parse.LogInCallback;
import com.parse.ParseException;
import com.parse.ParseFile;
import com.parse.ParseObject;
import com.parse.ParseQuery;
import com.parse.ParseUser;
import com.parse.SaveCallback;

import fr.curriculumvitae.anthony.stephan.constants.FileConstants;
import fr.curriculumvitae.anthony.stephan.objects.Message;
import fr.curriculumvitae.anthony.stephan.objects.State;
import fr.curriculumvitae.anthony.stephan.utils.Log;

public class BackEnd {
	
	  //////////
	 // AUTH // 
	//////////
	
	public static void authentification(String password, final IAuthentificationCallback callback) {
		ParseUser.logInInBackground("admin", password, new LogInCallback() {
			@Override
			public void done(ParseUser user, ParseException exception) {
				if(user != null && exception == null) {
					callback.authentificationEnded(true, null);
				} else {
					callback.authentificationEnded(false, exception.getMessage());
				}
			}
		});
	}
	
	
	  //////////
	 // POST // 
	//////////
	
	public static void postMessage(Message msg) {
		ParseObject message = new ParseObject(Message.PARSE_OBJECT_MESSAGE);
		message.put(Message.PARSE_FIELD_NAME, msg.getName());
		message.put(Message.PARSE_FIELD_FUNCTION, msg.getFunction());
		message.put(Message.PARSE_FIELD_ENTERPRISE, msg.getEnterprise());
		message.put(Message.PARSE_FIELD_EMAIL, msg.getEmail());
		message.put(Message.PARSE_FIELD_PHONE, msg.getPhone());
		message.put(Message.PARSE_FIELD_MESSAGE, msg.getMessage());
		message.put(Message.PARSE_FIELD_READ, msg.isRead());
		message.saveEventually();
	}
	
	public static void postMessage(Message msg, final IPostMessageCallback callback) {
		ParseObject message = new ParseObject(Message.PARSE_OBJECT_MESSAGE);
		message.put(Message.PARSE_FIELD_NAME, msg.getName());
		message.put(Message.PARSE_FIELD_FUNCTION, msg.getFunction());
		message.put(Message.PARSE_FIELD_ENTERPRISE, msg.getEnterprise());
		message.put(Message.PARSE_FIELD_EMAIL, msg.getEmail());
		message.put(Message.PARSE_FIELD_PHONE, msg.getPhone());
		message.put(Message.PARSE_FIELD_MESSAGE, msg.getMessage());
		message.put(Message.PARSE_FIELD_READ, msg.isRead());
		message.saveInBackground(new SaveCallback() {
			@Override
			public void done(ParseException exception) {
				if(exception != null) {
					callback.postEnded(false, exception.getMessage());
				} else {
					callback.postEnded(true, null);
				}
			}
		});
	}
	
	
	  /////////
	 // GET //
	/////////
	
	public static void getState(final IGetStateCallback callback) {
		ParseQuery<ParseObject> query = ParseQuery.getQuery(State.PARSE_OBJECT_STATE);
		query.findInBackground(new FindCallback<ParseObject>() {
			@Override
			public void done(List<ParseObject> objects, ParseException exception) {
				if(exception == null && objects != null) {
					Log.d("BackEnd", "getState.objects.size="+objects.size());
					if(objects.size() == 1) {
						boolean vacant = (Boolean) objects.get(0).get(State.PARSE_FIELD_VACANT);
						String disponibility = (String) objects.get(0).get(State.PARSE_FIELD_DISPONIBILITY);
						State state = new State(vacant, disponibility);
						callback.getStateEnded(true, state, null);
					} else {
						callback.getStateEnded(false, null, "can\'t get state : list.size!=1");
					}
				} else {
					Log.d("BackEnd", "getState.objects.exception="+exception.getMessage());
					callback.getStateEnded(false, null, exception.getMessage());
				}
			}
		});
	}
	
	
	public static void getPdfCV(final IGetPdfCVCallback callback) {
		ParseQuery<ParseObject> query = ParseQuery.getQuery("CVFile");
		query.findInBackground(new FindCallback<ParseObject>() {
			@Override
			public void done(List<ParseObject> objects, ParseException exception) {
				if(exception == null && objects != null) {
					Log.d("BackEnd", "getState.objects.size="+objects.size());
					if(objects.size() == 1) {
						ParseFile file = (ParseFile) objects.get(0).get("pdf");
						file.getDataInBackground(new GetDataCallback() {
							@Override
							public void done(byte[] bytes, ParseException exception2) {
								try {
									//Creating new File in sdcard
									File dir = FileConstants.FILE_PATH_STORAGE; 
									String filename = FileConstants.FILE_NAME_PDF_CV; 
									File createfile = new File(dir, filename); 
									createfile.mkdirs();
									//Writing into the PDF File
									File outputFile = new File(createfile, filename);
									FileOutputStream pdffos = new FileOutputStream(outputFile);
									pdffos.write(bytes);
									pdffos.flush();
									pdffos.close();
									// notify
									callback.getPdfCVEnded(true, outputFile, null);
								} catch (FileNotFoundException e) {
									callback.getPdfCVEnded(false, null, "FileNotFoundException");
								} catch (IOException e) {
									callback.getPdfCVEnded(false, null, "IOException");
								}
							}
						});
					} else {
						callback.getPdfCVEnded(false, null, "can\'t get pdf : list.size!=1");
					}
				} else {
					Log.d("BackEnd", "getState.objects.exception="+exception.getMessage());
					callback.getPdfCVEnded(false, null, exception.getMessage());
				}
			}
		});
	}
	
	
	public static void getMessages(final IGetMessagesCallback callback) {
		ParseQuery<ParseObject> query = ParseQuery.getQuery(Message.PARSE_OBJECT_MESSAGE);
		query.addDescendingOrder("createdAt");
		query.findInBackground(new FindCallback<ParseObject>() {
			@Override
			public void done(List<ParseObject> messages, ParseException exception) {
				if(exception != null) {
					callback.getMessagesEnded(false, null, exception.getMessage());
				} else {
					if(messages != null) {
						LinkedList<Message> list = new LinkedList<Message>();
						for(ParseObject po : messages) {
							Message msg = new Message();
							msg.setObjectId(po.getObjectId());
							msg.setCreatedAt(po.getCreatedAt());
							msg.setName(po.getString(Message.PARSE_FIELD_NAME));
							msg.setFunction(po.getString(Message.PARSE_FIELD_FUNCTION));
							msg.setEnterprise(po.getString(Message.PARSE_FIELD_ENTERPRISE));
							msg.setEmail(po.getString(Message.PARSE_FIELD_EMAIL));
							msg.setPhone(po.getString(Message.PARSE_FIELD_PHONE));
							msg.setMessage(po.getString(Message.PARSE_FIELD_MESSAGE));
							msg.setRead(po.getBoolean(Message.PARSE_FIELD_READ));
							list.add(msg);
						}
						callback.getMessagesEnded(true, list, null);
					} else {
						callback.getMessagesEnded(false, null, "message list is null");
					}
				}
			}
		});
	}
	
	
	  //////////
	 // EDIT //
	//////////
	
	public static void updateMessage(final Message msg, final boolean markAsRead, final IEditMessageCallback callback) {
		ParseQuery<ParseObject> query = ParseQuery.getQuery(Message.PARSE_OBJECT_MESSAGE);
		query.getInBackground(msg.getObjectId(), new GetCallback<ParseObject>() {
			public void done(ParseObject po, ParseException e) {
				if (e == null) {
					po.put(Message.PARSE_FIELD_READ, markAsRead);
					po.saveInBackground();
					callback.editMessageEnded(true, msg.getObjectId(), null);
				} else {
					callback.editMessageEnded(false, null, e.getMessage());
				}
			}
		});
	}

}
